package net.quanter.demo.junit5.basic.idcard;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.github.houbb.opencc4j.util.ZhConverterUtil;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;

/***
 * 身份证校验转换
 * created on 2021-01-22
 * @author 王老实
 *
 */
public class IdCardChange {

    private static char[] chars = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X'};
    private static final String regex = "\\(.*?\\)";
    //private static final String regex = "\\([^}]*\\) ";

    /**
     * 身份证转换
     *
     * @param entity
     * @return
     */
    public static Entity idCardChange(Entity entity) {
        //1.身份证号码将所有可能出错的特殊字符转换成正确的字符
        entity.idCard = entity.idCard
            .replaceAll("x|ｘ|✘|Ｘ|ⅹ|Ⅹ", "X")//类X字符全部转换成半角大写的X
            .replaceAll("o|O|ｏ|Ｏ|０", "0");//所有的类0字符都转变成半角数字0
        //2.去掉出0-9以及X以外的特殊字符
        char[] idCardChars = entity.idCard.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < idCardChars.length; i++) {
            int asc = idCardChars[i];
            if ((asc >= 48 && asc <= 57) || (asc == 88)) {
                //满足条件
                sb.append(idCardChars[i]);
            }
        }
        entity.idCard = sb.toString();
        //3.姓名里去掉括号里的内容所有全半角里的括号

        entity.name = entity.name
            .replaceAll("\\{|《|【|\\<|<|\\{|「|『|\\[|（", "(")
            .replaceAll("\\}|》|】|\\>|>|\\}|」|』|\\]|）", ")")
            .replaceAll(" |　", "");

        String replaceName = entity.name
            .replaceAll(regex, "");
        //去过去掉括号里的内容不剩啥了，说明括号里就是名字
        if ("".equals(replaceName)) {
            entity.name = entity.name.replaceAll("\\(", "")
                .replaceAll("\\)", "");
        } else {
            entity.name = replaceName;
        }
        entity.name = removeAllSpecialChar(entity.name);
        return entity;
    }

    /**
     * 是否包含简体字
     *
     * @param str
     * @return
     */
    public static boolean containTraditional(String str) {
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            boolean b = ZhConverterUtil.isTraditional(String.valueOf(chars[i]));
            if (b) {
                return true;
            }
        }
        return false;
    }

    /**
     * 繁体转简体
     *
     * @param str
     * @return
     */
    public static String toTraditional(String str) {
        if (containTraditional(str)) {
            return ZhConverterUtil.toSimple(str);
        }
        return str;
    }

    public static String removeAllSpecialChar(String str) {
        char[] chars = str.toCharArray();
        List<Character> charList = new ArrayList<>();
        for (int i = 0; i < chars.length; i++) {
            int ascii = (int)chars[i];
            if ( (ascii>=65 && ascii<=90) //大写英文字母
                || (ascii>=97 && ascii<=122) //小写英文字母
                || (ascii==183) //新疆人特殊字符·
                || (ascii==46) //新疆人特殊字符·
                || (ascii>=11905 && ascii<=12019) //汉字偏旁部首
                || (ascii>=12032 && ascii<=12245) //汉字
                || (ascii>=12449 && ascii<=12588) //汉字
                || (ascii>=12689 && ascii<=12751) //汉字
                || (ascii>=12784 && ascii<=12799) //汉字
                || (ascii>=13312 && ascii<=40917) //汉字
                || (ascii>=13312 && ascii<=40917) //汉字
                || (ascii>=57524 && ascii<=61111) //好像是宋体汉字
                || (ascii>=62368 && ascii<=63152) //好像是宋体汉字
                || (ascii>=63744 && ascii<=64109) //好像是宋体汉字
            ) {
                charList.add(chars[i]);
            }
        }
        StringBuilder sb = new StringBuilder();
        for(Character c :charList){
            sb.append(c);
        }

        return sb.toString();
    }

    /**
     * 是否全角
     *
     * @param str
     * @return
     */
    public static boolean isAllJiao(String str) {
        try {
            byte[] b = str.getBytes("unicode");
            return true;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 从身份证里获取生日
     * @param idCard 身份证
     * @param format 格式化
     * @return
     */
    public static String getBirthday(String idCard,String format) {
        if(idCard==null || idCard.length()<14){
            return null;
        }
        String birthday = idCard.substring(6, 14);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(format);
        try{
            Date date = simpleDateFormat.parse(birthday);
            String result = simpleDateFormat1.format(date);
            return result;
        }catch (ParseException e){
            //如果出现格式转换异常，则说明第一次身份证格式错误，进行身份证的纠正
            String newIdCard = correctIdCard(idCard);
            if(newIdCard==null || newIdCard.length()<14){
                return null;
            }
            String newBirthday = newIdCard.substring(6, 14);
            Date newDate = null;
            try {
                newDate = simpleDateFormat.parse(newBirthday);
                String result = simpleDateFormat1.format(newDate);
                return result;
            } catch (ParseException parseException) {
                return null;
            }
        }
    }

    public static int getGender(String idCard) {
        if(idCard==null || idCard.length()<15){
            return 1;
        }
        String gender = idCard.substring(idCard.length()-2, idCard.length()-1);
        try{
            boolean isMale = Integer.parseInt(gender) % 2 != 0;
            if(isMale){
                return 1;
            }else {
                return 0;
            }
        }catch (NumberFormatException e){
            //如果出现格式转换异常，则说明第一次身份证格式错误，进行身份证的纠正
            String newIdCard = correctIdCard(idCard);
            String newGender = newIdCard.substring(idCard.length()-2, idCard.length()-1);

            try {
                boolean isMale = Integer.parseInt(newGender) % 2 != 0;
                if(isMale){
                    return 1;
                }else {
                    return 0;
                }
            } catch (NumberFormatException parseException) {
                return 1;
            }
        }
    }

    private static String correctIdCard(String oldIdCard){
        String newIdCard = oldIdCard
            .replaceAll("x|ｘ|✘|Ｘ|ⅹ|Ⅹ", "X")//类X字符全部转换成半角大写的X
            .replaceAll("o|O|ｏ|Ｏ|０", "0");//所有的类0字符都转变成半角数字0
        //2.去掉出0-9以及X以外的特殊字符
        char[] idCardChars = newIdCard.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < idCardChars.length; i++) {
            int asc = idCardChars[i];
            if ((asc >= 48 && asc <= 57) || (asc == 88)) {
                //满足条件
                sb.append(idCardChars[i]);
            }
        }
        return sb.toString();
    }


    @Data
    @Builder
    @EqualsAndHashCode
    public static class Entity {
        private String idCard;
        private String name;
    }
}
